package com.icinfo.cloud.provider.common.crontask;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.utils.SpringContextUtil;
import com.icinfo.cloud.provider.peripheralinterface.electricinvoice.dto.ElectricInvoiceRequest;
import com.icinfo.cloud.provider.peripheralinterface.electricinvoice.service.IElectricInvoiceInterface;
import com.icinfo.cloud.provider.punish.common.documentoperate.dto.RebuildDocumentDto;
import com.icinfo.cloud.provider.punish.common.documentoperate.service.IStageDocCommonOperateService;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.CaseTypeEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.mapper.CaseDocumentRecordMapper;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CaseDocumentRecord;
import com.icinfo.cloud.provider.punish.ucase.casemain.service.ICaseDocumentRecordService;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseMainInfoVo;
import com.icinfo.cloud.provider.punish.ucase.payment.dto.PaymentElectricInvoiceKeyInfoDto;
import com.icinfo.cloud.provider.punish.ucase.payment.mapper.CasePaymentResultRecordMapper;
import com.icinfo.cloud.provider.punish.ucase.payment.model.CasePaymentResultRecord;
import com.icinfo.cloud.provider.punish.ucase.payment.service.ICasePaymentResultRecordService;
import com.icinfo.framework.common.web.Result;
import com.icinfo.framework.mybatis.mapper.entity.Example;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 描述：统一支付定时任务
 *
 * @author xiangyuyu
 * @date 2022/10/12
 * @since 1.4.2
 */

@Configuration
@EnableScheduling
@Slf4j
@RestController
@RequestMapping("/unifiedPaymentTask")
public class UnifiedPaymentTask {
    @Resource
    private IElectricInvoiceInterface electricInvoiceInterface;
    @Resource
    private ICasePaymentResultRecordService casePaymentResultRecordService;
    @Resource
    private IStageDocCommonOperateService stageDocCommonOperateService;
    @Resource
    private ICaseDocumentRecordService caseDocumentRecordService;
    @Resource
    private CaseDocumentRecordMapper caseDocumentRecordMapper;
    @Resource
    private CasePaymentResultRecordMapper casePaymentResultRecordMapper;
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    private static final String SYN_PAYMENT_ELECTRIC_INVOICE_NEW_REDIS_KEY = "PUNISH:TASK:SYN_PAYMENT_ELECTRIC_INVOICE_NEW_REDIS_KEY";

    /**
     * 描述：同步缴款电子发票
     *
     * @author xiangyuyu
     * @date 2022/10/12
     * @since 1.4.2
     */
    @ApiOperation(value = "同步缴款电子发票", httpMethod = "POST")
    @PostMapping("/synchronizePaymentElectricInvoice")
    //@Scheduled(cron = "0 0 6,12,18,23 * * ? ")
    //ljy注掉测试
    @Scheduled(cron = "0 */10 * * * ? ")
    public void synchronizePaymentElectricInvoice() {
        //防止多台服务器重复执行（过期时间设置为10分钟，预防服务器时间不同步）
        if (!redisTemplate.opsForValue().setIfAbsent(SYN_PAYMENT_ELECTRIC_INVOICE_NEW_REDIS_KEY, SYN_PAYMENT_ELECTRIC_INVOICE_NEW_REDIS_KEY, 1, TimeUnit.MINUTES)) {
            log.info("--------当前服务器未拿到分布式锁，不执行逻辑----------");
            return;
        }
        LocalDateTime startTime = LocalDateTime.now();
        log.info("synchronizePaymentElectricInvoice start-startTime:{}", startTime);
        List<PaymentElectricInvoiceKeyInfoDto> needDealList = new ArrayList<>();
        //获取到有缴款结果的，没有电子发票的案件
        List<PaymentElectricInvoiceKeyInfoDto> needDealListOrdinary = casePaymentResultRecordMapper.selectNeedReceiveInvoiceCaseInfoOrdinary();
        //增加简易处罚相关案件信息
        List<PaymentElectricInvoiceKeyInfoDto> needDealListSimple = casePaymentResultRecordMapper.selectNeedReceiveInvoiceCaseInfoSimple();
        if (!ObjectUtils.isEmpty(needDealListOrdinary) && needDealListOrdinary.size() > 0) {
            needDealList.addAll(needDealListOrdinary);
        }
        if (!ObjectUtils.isEmpty(needDealListSimple) && needDealListSimple.size() > 0) {
            needDealList.addAll(needDealListSimple);
        }
        if (needDealList.size() > 0) {
            needDealList.forEach(caseInfo -> {
                String caseId = caseInfo.getCaseId();
                ElectricInvoiceRequest request;
                if (SpringContextUtil.checkIsPrdProfile()) {
                    request = new ElectricInvoiceRequest(null, caseInfo.getCertificateNo(), caseInfo.getCheckCode(), caseInfo.getEnterCode(), Constant.STRING_2,caseInfo.getElectricInvoiceAddress());
                } else {
                    request = new ElectricInvoiceRequest(null, caseInfo.getCertificateNo(), caseInfo.getCheckCode(), caseInfo.getEnterCode(), Constant.STRING_2,caseInfo.getElectricInvoiceAddress());
                }
                //获取电子发票
                try {
                    List<String> electricInvoiceInfo = electricInvoiceInterface.getElectricInvoice(request);
                    if (!ObjectUtils.isEmpty(electricInvoiceInfo) && electricInvoiceInfo.size() > 0) {
                        boolean flag = dealAfterReceiveElectricInvoice(electricInvoiceInfo, caseInfo);
                        if (flag) {
                            log.info("synchronizePaymentElectricInvoice caseId:" + caseId + "success");
                        } else {
                            log.info("synchronizePaymentElectricInvoice caseId:" + caseId + "fail");
                        }
                    } else {
                        log.warn("未获取到发票信息");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        }
        LocalDateTime endTime = LocalDateTime.now();
        Duration duration = Duration.between(startTime, endTime);
        long seconds = duration.getSeconds();
        log.info("synchronizePaymentElectricInvoice end-endTime:{},consume:{} s", endTime, seconds);
    }

    /**
     * 描述：电子发票获取后的后续操作
     *
     * @param electricInvoiceInfo 电子发票
     * @param caseInfo            {@link PaymentElectricInvoiceKeyInfoDto}
     * @return boolean 是否保存成功
     * @author xiangyuyu
     * @date 2022/10/12
     * @since 1.4.2
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean dealAfterReceiveElectricInvoice(List<String> electricInvoiceInfo, PaymentElectricInvoiceKeyInfoDto caseInfo) {
        //更新电子发票地址
        String electricInvoiceAddress = electricInvoiceInfo.stream().collect(Collectors.joining(Constant.STRING_COMMA));
        List<Object> zjyjList = new ArrayList<>();
        String caseId = caseInfo.getCaseId();
        String partyId = caseInfo.getPartyId();
        Map<String, String> zjyjMap = new HashMap<>(20);
        String documentCataLogCode = caseInfo.getDocumentCatalogCode();
        electricInvoiceInfo.forEach(e -> {
            //将电子发票转换为图片
            //String imageBase64 = PdfUtil.pdfTransImage(e);
            zjyjMap.put("ZXQKJL_AUTO_ZJYJ",e);
            zjyjList.add(zjyjMap);
            //添加电子发票附件
            CaseMainInfoVo caseMainInfo = new CaseMainInfoVo();
            caseMainInfo.setId(caseId);
            caseMainInfo.setCaseCurrentStageCode(caseInfo.getCaseCurrentStageCode());
            caseMainInfo.setCaseCurrentStageName(caseInfo.getCaseCurrentStageName());
            caseMainInfo.setCaseCurrentLinkCode(caseInfo.getCaseCurrentLinkCode());
            caseMainInfo.setCaseCurrentLinkName(caseInfo.getCaseCurrentLinkName());
            //将电子发票保存到附件信息
            casePaymentResultRecordService.addAttachmentElectricInvoice
                    (caseMainInfo, documentCataLogCode, e, partyId);
        });
        String caseType = caseInfo.getCaseType();
        String noticeNo = caseInfo.getNoticeNo();
        if (CaseTypeEnum.SIMPLE_PROCEDURE.getCode().equals(caseType)) {
            //更新电子发票地址
            return updateElectricInvoiceAddressInfo(caseId, noticeNo, electricInvoiceAddress);
        } else {
            //根据caseId+documentCatalogCode查询出文书id
            CaseDocumentRecord caseDocumentRecord = caseDocumentRecordService.getCaseDocumentRecord(caseId, documentCataLogCode);
            String documentContent = caseDocumentRecord.getDocumentContent();
            JSONObject jsonObject = JSON.parseObject(documentContent);
            jsonObject.put("ZJYJ_AUTO_LIST", zjyjList);
            if (!ObjectUtils.isEmpty(caseDocumentRecord)) {
                String documentId = caseDocumentRecord.getId();
                //重新赋值 documentContent，并且更新
                CaseDocumentRecord newRecord = new CaseDocumentRecord();
                newRecord.setId(documentId);
                newRecord.setDocumentContent(jsonObject.toJSONString());
                int updateCount = caseDocumentRecordMapper.updateByPrimaryKeySelective(newRecord);
                if (updateCount > 0) {
                    //重新生成执行情况记录
                    RebuildDocumentDto dto = new RebuildDocumentDto(documentId, "");
                    Map<String, Object> paramJson = new HashMap<>(8);
                    List<RebuildDocumentDto> list = new ArrayList<>();
                    list.add(dto);
                    paramJson.put("documentInfo", list);
                    Result<Map<String, Object>> result = stageDocCommonOperateService.rebuildPdf(paramJson);
                    if (ObjectUtil.isNotEmpty(result) && HttpStatus.HTTP_OK == result.getCode()){
                        int num = (int) result.getData().get("num");
                        if (num>0){
                            //更新电子发票地址
                            return updateElectricInvoiceAddressInfo(caseId, noticeNo, electricInvoiceAddress);
                        }else {
                            return false;
                        }
                    }  else {
                        return false;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 描述：更新缴款结果记录中的电子发票信息
     *
     * @param caseId                 案件id
     * @param noticeNo               缴款单号
     * @param electricInvoiceAddress 电子发票地址
     * @return 更新是否成功（true-是/false-否）
     * @author xiangyuyu
     * @date 2022/10/19
     * @since 1.4.2
     */
    private boolean updateElectricInvoiceAddressInfo(String caseId, String noticeNo, String electricInvoiceAddress) {
        Example updateE = new Example(CasePaymentResultRecord.class);
        Example.Criteria c = updateE.createCriteria();
        c.andEqualTo("caseId", caseId);
        c.andEqualTo("noticeNo", noticeNo);
        CasePaymentResultRecord record = new CasePaymentResultRecord();
        record.setElcInvoicePicUrl(electricInvoiceAddress);
        int uc = casePaymentResultRecordMapper.updateByExampleSelective(record, updateE);
        if (uc > 0) {
            return true;
        }
        return false;
    }
}
